package com.cgnpc.scp.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;

public class StringUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(StringUtil.class);

    /**
     * UTF-8编码
     */
    public static final String CHARSET_UTF8 = "UTF-8";

    public static final String CHARSET_ISO8859_1 = "ISO8859-1";

    /**
     * 数字的正则表达式
     */
    public static final Pattern PATTERN_NUMBER_SIMPLE = Pattern.compile("^[+-]?\\d+(.\\d*)?$");

    /**
     * int的正则表达式
     */
    public static final Pattern PATTERN_INTEGER_SIMPLE = Pattern.compile("^[+-]?\\d+$");

    /**
     * double的.0表示方式
     */
    public static final Pattern PATTERN_DOUBLE_ZERO_SIMPLE = Pattern.compile("^[+-]?\\d+(.0*)?$");

    /**
     * Sql中不安全的字符
     */
    private static final List<String> UNSAFE_CHAR_WITH_SQL_LIST = Arrays.asList(
            "'", // 单引号
            "\"", // 双引号
            // 反斜杠单引号
            // 反斜杠双引号
            ")", // 括号
            ";", // 分号
            "--", // 双减号
            "+" // 加号
    );

    /**
     * 是否为空，或者空白
     *
     * @param val 值
     * @return true:为空或空白；false:非空
     */
    public static boolean isNullOrSpace(String val) {
        return val == null || val.length() == 0 || val.trim().length() == 0;
    }

    /**
     * 判断是否包含空，空白字符串
     *
     * @param vals 字符串，字符串数组
     * @return true:包含为空或空白；false:全部非空
     */
    public static boolean hasNullOrSpace(String... vals) {
        if (vals == null || vals.length <= 0) {
            return true;
        }

        for (String valItem : vals) {
            if (isNullOrSpace(valItem)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 格式化Object为String，objVal为null则返回null，其他返回toString。
     *
     * @param objVal objVal
     * @return objVal为null则返回null，其他返回toString。
     */
    public static String formatObjectToString(Object objVal) {
        return objVal == null ? null : objVal.toString();
    }

    /**
     * 格式化Object为String，objVal==null则为""长度为0的字符串，其他返回toString。
     *
     * @param objVal objVal
     * @return objVal==null则为""长度为0的字符串，其他返回toString。
     */
    public static String formatObjectToStringLen0(Object objVal) {
        return objVal == null ? "" : objVal.toString();
    }

    /**
     * 是否为数字字符串
     */
    public static boolean isNumberSimpleString(String val) {
        return val != null && PATTERN_NUMBER_SIMPLE.matcher(val).matches();
    }

    /**
     * 是否为整数字符串
     */
    public static boolean isIntegerSimpleString(String val) {
        return val != null && PATTERN_INTEGER_SIMPLE.matcher(val).matches();
    }

    /**
     * 是否为double的小数点为0
     */
    public static boolean isDoubleZeroSimpleString(String val) {
        return val != null && PATTERN_DOUBLE_ZERO_SIMPLE.matcher(val).matches();
    }

    /**
     * 格式化字符串，如果为null返回长度0的字符串
     *
     * @param str 字符串
     * @return str==null则为""长度为0的字符串，其他返回toString。
     */
    public static String formatStringToLen0(String str) {
        return str == null ? "" : str;
    }

    /**
     * SQL替换不安全的字符
     *
     * @param str
     */
    public static String replaceUnsafeCharWithSql(String str) {
        if (str == null) {
            return null;
        }

        if (ListUtil.getListSizeWith0(UNSAFE_CHAR_WITH_SQL_LIST) <= 0) {
            return str;
        }

        StringBuilder sbInfo = new StringBuilder(str);
        int charIndex = 0;
        boolean hasNextFromFirst = true; // 删除一些字符之后可能构成了新的不安全字符，需要重复校验删除之后的新字符

        while (hasNextFromFirst) {
            hasNextFromFirst = false;

            for (String filterChar : UNSAFE_CHAR_WITH_SQL_LIST) {
                while ((charIndex = sbInfo.indexOf(filterChar)) != -1) {
                    sbInfo.delete(charIndex, charIndex + filterChar.length());
                    hasNextFromFirst = true;
                }
            }
        }

        return sbInfo.toString();
    }

    /**
     * 校验是否包含不安全字符
     *
     * @param str 值true安全；false不安全；如果为null则返回安全true；
     */
    public static boolean hasUnsafeCharWithSql(final String logInfo, String str) {
        if (str == null) {
            return false;
        }

        if (ListUtil.getListSizeWith0(UNSAFE_CHAR_WITH_SQL_LIST) <= 0) {
            return false;
        }

        for (String unsafeChar : UNSAFE_CHAR_WITH_SQL_LIST) {
            if (str.indexOf(unsafeChar) != -1) {
                LOGGER.error("{}unsafeChar:[{}];str:[{}];", logInfo, unsafeChar, str);
                return true;
            }
        }

        return false;
    }

    public static String getUuid32() {
        return UUID.randomUUID().toString().replace("-", "");
    }

}
